/**
 * 
 */
package br.edu.ufcg.embedded.mysocial;

import java.sql.Timestamp;
import java.util.Hashtable;
import java.util.LinkedHashSet;
import java.util.List;

import org.jgrapht.alg.BellmanFordShortestPath;
import org.jgrapht.graph.DefaultEdge;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;

import br.edu.ufcg.embedded.util.Compressor;
import br.edu.ufcg.embedded.util.MultiFileGenerator;
import br.embedded.socialapp.business.Usuario;

/**
 * @author daniel
 *
 */
public class GraphCache2 extends Thread
{
	private List<String> list;
	private int maxLevels;
	private MultiFileGenerator multiFileGenerator;
	private Compressor compressor;
	
	public GraphCache2(int maxLevels, List<String> list)
	{
		this.list = list;
		this.maxLevels = maxLevels;
		
		this.compressor = new Compressor();
	}
	
	/**
	 * @param fileManager the fileManager to set
	 */
	public void setMultiFileGenerator(MultiFileGenerator multiFileGenerator) {
		this.multiFileGenerator = multiFileGenerator;
	}
	
	private void cacheFriendshipLevels()
	{
		for (int i = 0; i < list.size(); i++)
		{
			Hashtable<Integer, LinkedHashSet<String>> hashtable = new Hashtable<Integer, LinkedHashSet<String>>();
			
			BellmanFordShortestPath<String, DefaultEdge> alg = (maxLevels > 0) ?  
				new BellmanFordShortestPath<String, DefaultEdge>(GraphCacheManager.getGraph(), list.get(i), maxLevels) 
				: new BellmanFordShortestPath<String, DefaultEdge>(GraphCacheManager.getGraph(), list.get(i));
			
			String nextUser = (i < list.size() -1) ? list.get(i+1) : list.get(0);
			//Usuario nextUser = (i < list.size() -1) ? list.get(i+1) : list.get(0);
			
			alg.getPathEdgeList(nextUser);
			
			List<String> reachableVertices = alg.getReachableVertices();
			
/*			if (!hashtable.containsKey(currentUsuario))
				hashtable.put(currentUsuario, new Hashtable<Integer, LinkedHashSet<String>>());*/
			
			for (int j = 1; j < reachableVertices.size(); j++) {
				
				List<DefaultEdge> edgeList = alg.getPathEdgeList(reachableVertices.get(j));
				
				if (!hashtable.containsKey(edgeList.size()))
					hashtable.put(edgeList.size(), new LinkedHashSet<String>());
				
				//if (!hashtable.get(currentUsuario).get(edgeList.size()).contains(reachableVertices.get(j).getLogin()))
					hashtable.get(edgeList.size()).add(reachableVertices.get(j));//.getLogin());
			}
			write(list.get(i)/*.getLogin()*/, hashtable);
			hashtable = null;
		}
		multiFileGenerator.close();
	}
	
	@Override
	public void run() {
		this.cacheFriendshipLevels();
	}
	
	private void write(String login, Hashtable<Integer, LinkedHashSet<String>> hashtable)
	{
		XStream xstream = new XStream(new JettisonMappedXmlDriver());
		byte[] compressedData = compressor.compress(xstream.toXML(hashtable));
		multiFileGenerator.write(login + ";" + compressedData + ";" + new Timestamp(System.currentTimeMillis()) + ";" + compressedData.length);
		
		hashtable = null;
		login = null;
		compressedData = null;
	}
}
